<?php

namespace app\api\controller;

use app\service\UserService;
use app\services\AuthService;
use app\services\ConfigService;
use app\services\PaymentService;
use app\services\SmsService;
use app\services\TokenService;
use EasyWeChat\Factory;
use plugin\admin\app\common\Util;
use plugin\admin\app\model\Payment;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserProfile;
use support\Db;
use support\login\LoginFactory;
use support\Request;
use support\Socialite;

class AuthController
{
    public function authList(Request $request)
    {
        try {
            $data = AuthService::list();
            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getMobileFromWechatEncryptData($request)
    {
        $code = $request->post('code');

        $config = ConfigService::getByGroup('wechat');
        $app = Factory::miniProgram([
            'app_id' => $config['wechat_app_id'],
            'secret' => $config['wechat_app_secret'],
            'response_type' => 'array'
        ]);

        $res = $app->phone_number->getUserPhoneNumber($code);

        return $res;
    }

    public function register(Request $request)
    {
        $nickname = $request->post('nickname');
        $avatar = $request->post('avatar');
        $openId = $request->post('open_id');
        $inviteCode = $request->post('invite_code');
        $mobile = $request->post('mobile');

        $testModel = 0;
        $phoneNumber = '';
        if (getenv('APP_DEBUG')) {
            $testModel = $request->post('develop_model', 0);
            $phoneNumber = $request->post('phone_number', 0);
        }

        try {
            Db::beginTransaction();

            if ($testModel) {
                $res = [
                    'phone_info' => [
                        'phoneNumber' => $phoneNumber
                    ]
                ];
            } else {
                $res = [
                    'phone_info' => [
                        'phoneNumber' => $mobile
                    ]
                ];
            }
            $mobile = $res['phone_info']['phoneNumber'] ?? '';

            if (!$mobile) {
                throw new \Exception('获取手机号失败，请尝试重新获取');
            }
            $userId = \app\services\UserService::register(compact('mobile', 'avatar', 'nickname', 'openId', 'inviteCode'));
            $token = TokenService::generate($userId);
            Db::commit();
            return ok_rsp('成功', ['token' => $token]);
        } catch (\Exception $e) {
            Db::rollBack();
            return err_rsp($e->getMessage());
        }
    }

    public function isExists(Request $request)
    {
//        $iv = $request->post('iv');
//        $encryptedData = $request->post('encryptedData');

        $loginCode = $request->post('login_code');
        $developModel = 0;
        if (getenv('APP_DEBUG')) {
            $developModel = $request->post('develop_model');
            $phoneNumber = $request->post('phone_number');
        }

        if ($developModel) {
            $res = [
                'phone_info' => [
                    'phoneNumber' => $phoneNumber
                ]
            ];
        } else {
            $res = $this->getMobileFromWechatEncryptData($request);
        }

        $mobile = $res['phone_info']['phoneNumber'] ?? '';

        if (!$mobile) {
            throw new \Exception('获取手机号失败，请尝试重新获取');
        }

        try {
            $config = ConfigService::getByGroup('wechat');
            $app = Factory::miniProgram([
                'app_id' => $config['wechat_app_id'],
                'secret' => $config['wechat_app_secret'],
                'response_type' => 'array'
            ]);

            $loginRes = $app->auth->session($loginCode);

            $user = User::where('mobile', $mobile)->first();

            if (!$user) {
                return ok_rsp('成功', ['is_exists' => false, 'mobile' => $mobile, 'open_id' => $loginRes['openid']]);
            }

            if (empty($user['mini_open_id'])) {
                $user['mini_open_id'] = $loginRes['openid'];
                $user->save();
            }

            return ok_rsp('登录成功', [
                'is_exists' => true,
                'token' => TokenService::generate($user['id'])
            ]);
        } catch (\Exception $e) {
            echo $e->getMessage() . $e->getTraceAsString();
            return err_rsp($e->getMessage());
        }
    }

    public function loginByCode(Request $request)
    {
        $code = $request->post('code');
        $type = $request->post('type');

        try {
            $app = Socialite::getInstance($type);

            $info = $app->userFromCode($code);

            $user = User::where(Socialite::getOpenField($type), $info->getId())->first();

            if (!$user) {
                return ok_rsp('成功', ['exists' => false, 'open_id' => $info->getId()]);
            }

            $token = TokenService::generate($user['id']);
            return ok_rsp('成功', ['token' => $token, 'exists' => true]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function bindUser(Request $request)
    {
        $mobile = $request->post('mobile');
        $email = $request->post('email');
        $type = $request->post('type');
        $openId = $request->post('open_id');

        try {
            if (empty($mobile) && empty($email)) {
                throw new \Exception('手机号或邮箱不能为空');
            }

            $user = User::where('mobile', $mobile)->orWhere('email', $email)->first();

            if (!$user) {
                throw new \Exception('不存在的用户');
            }

            $user[Socialite::getOpenField($type)] = $openId;
            $user->save();

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }


    }

    public function login(Request $request)
    {
        $data= $request->post();
        $loginType = $request->post('login_type');

        try {
            Db::beginTransaction();
            $auth = LoginFactory::createInstance($loginType);
            $user = $auth->check($data);

            if ($user['status']) {
                throw new \Exception('您的账号已被禁用,请联系管理员解禁');
            }

            $token = TokenService::generate($user['id']);

            $profileFinishRate = \app\services\UserService::getProfileRate(UserProfile::where('user_id', $user['id'])->first()->toArray());

            Db::commit();
            return ok_rsp('成功', ['token' => $token, 'need_finish_info' => $profileFinishRate < 100]);
        } catch (\Exception $e) {
            Db::rollBack();
            return err_rsp($e->getMessage());
        }
    }

    public function logout(Request $request)
    {
        try {
            TokenService::destroy($request->header('token'));

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function findPasswordByOldPassword(Request $request)
    {
        $oldPassword = $request->post('old_password');
        $password = $request->post('new_password');
        $confirmPassword = $request->post('confirm_new_password');

        $userId = get_user_id();

        $userInfo = User::find($userId);

        try {
            if (!Util::passwordVerify($oldPassword, $userInfo['password'])) {
                throw new \Exception('原密码不正确');
            }

            if ($password != $confirmPassword) {
                throw new \Exception('两次密码输入不一致');
            }

            $userInfo->password = Util::passwordHash($password);
            $userInfo->save();

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }

    }

    public function findPassword(Request $request)
    {
        $mobile = $request->post('mobile');
        $captcha = $request->post('captcha');
        $password = $request->post('password');
        $confirmPassword = $request->post('confirm_password');

        try {

            if (empty($mobile)) {
                if (get_user_id()) {
                    $user = User::find(get_user_id());
                    $mobile = $user['mobile'];
                } else {
                    throw new \Exception('手机号不能为空');

                }
            }

            if ($password != $confirmPassword) {
                throw new \Exception('两次密码输入不一致');
            }

            $user = User::where('mobile', $mobile)->first();

            if (!$user) {
                throw new \Exception('不存在的用户');
            }

            SmsService::check($mobile, SmsService::FIND_PASSWORD, $captcha);

            $user->password = Util::passwordHash($password);
            $user->save();

            return ok_rsp('修改密码成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }
}